<template>
    <div class="stats" ref="statsRef"></div>
    <div class="container" ref="containerRef">
    </div>
</template>

<script setup>

import { ref, onMounted, onActivated } from 'vue'
import {
    Scene, PerspectiveCamera,
    WebGLRenderer,
    AxesHelper,
    AmbientLight,
    SRGBColorSpace,PointLight,
    DirectionalLight
} from 'three'

import model15 from './model15'

import { OrbitControls } from 'three/examples/jsm/Addons.js'
import Stats from 'three/examples/jsm/libs/stats.module.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
// import Stats from 'stats.js'
const stats = new Stats()
stats.showPanel(0)
stats.dom.style.top = '50px'
const statsRef = ref(null)
const containerRef = ref(null)

// 创建GUI可视化交互
const gui = new GUI()

gui.domElement.style.right = '0px'
gui.domElement.style.width = '300px'

// 创建需要修改的对象
const obj = {
    x1: false,
    x2: 'top',
    x3: 'left'
}

const addFolder1 = gui.addFolder('单选')
// 单选
addFolder1.add(obj, 'x1').name("设置x1")
const addFolder2 = gui.addFolder('下拉选')
// 设置默认不展开
addFolder2.close()
// 下拉选择
addFolder2.add(obj, 'x2', ['top', 'bottom']).name("设置x2")
addFolder2.add(obj, 'x3', {
    '左': 'left',
    '右': 'right'
}).name("设置x3")

// 创建一个场景
const scene = new Scene()

// 创建三维坐标轴,参数为坐标轴的大小，一般比物体的大就行了
const axesHelper = new AxesHelper(300)
// 将三维坐标添加到场景中
scene.add(axesHelper)

scene.add(model15);


// //  设置光源 参数一表示灯光颜色，参数二表示光照强度
const pointLight = new PointLight(0xffffff, 0.5);
// 设置为0则表示光照强度不受距离的影响
// pointLight.decay = 0.0
// 设置灯光的位置
pointLight.position.set(0, 0, 0);
scene.add(pointLight);
// 环境光
const light = new AmbientLight('#FFFFFF', 0.5); // 柔和的白光
scene.add(light);
// .name('环境光光照强度') 设置别名  .step(0.2) 设置别名
gui.add(light, 'intensity', 0, 5).name('环境光光照强度').step(0.2).onChange(function (value) {
    console.log('修改的值', value)
})
gui.addColor(light, 'color').name('环境光颜色').onChange(function (value) {
    console.log('修改的值', value)
})


// 平行光
// 从上方照射的白色平行光，强度为 0.5。
const directionalLight = new DirectionalLight('#FFFFFF', 20);
// 设置观察位置坐标，也就是说光源照射到哪个坐标点上
directionalLight.position.set(30, 30, 0)
scene.add(directionalLight);

// 创建一个透视投影相机对象
const width = ref(window.innerWidth)
const height = ref(window.innerHeight)
const camera = new PerspectiveCamera(45, width.value / height.value, 1, 2000);
// const camera = new PerspectiveCamera(45, width.value / height.value, 1, 10000);
// 设置相机的位置
camera.position.set(400, 400, 400)
// camera.position.set(2000, 2000, 2000)
// 定义相机的视线（观察目标）,也就是相机对准哪个点去观察拍照的意思
camera.lookAt(0, 0, 0)
// camera.lookAt(1000, 0, 1000)
// // 也可以直接指向网格模型的位置
// camera.lookAt(cube.position)

// 将相机添加到场景中
scene.add(camera);

// 创建一个渲染器
const renderer = new WebGLRenderer({
    antialias: true  // 启用抗锯齿
})
// 设置背景颜色
// renderer.setClearColor(0xffff00)
// 设置设备像素比
renderer.setPixelRatio(window.devicePixelRatio)
// 设置渲染器画布的大小，一般为相机的宽高比
renderer.setSize(width.value, height.value)

// 设置渲染器的编码方式与加载器加载的模型编码一致，解决渲染颜色偏差问题
renderer.outputColorSpace = SRGBColorSpace

// 设置渲染哪个场景中的哪个相机，参数一为场景，参数二维相机
renderer.render(scene, camera)  // 类型相机的拍照动作，咔！！！

// 设置鼠标可操作，参数一为相机，参数二维渲染器的元素
const controls = new OrbitControls(camera, renderer.domElement)
// 重新更新相机的lookAt,set(1000, 0, 1000)为相机lookAt的值
controls.target.set(0, 0, 0)
controls.update()
// 监听是否发生变化，如果发生变化则重新渲染，渲染器
controls.addEventListener('change', function () {
    // 重新渲染器渲染器
    renderer.render(scene, camera)
})

console.log(window.devicePixelRatio)
function render() {
    // 性能监控end==================================>性能监控
    stats.update()
    // 性能监控end==================================>性能监控
    // 重新渲染渲染器
    renderer.render(scene, camera)
    // 启动动画自动加载
    requestAnimationFrame(render)
    // // 打印相机的lookAt
    // console.log('打印相机的lookAt',controls.target)
    // // 打印相机摆放位置
    // console.log('打印相机摆放位置',camera.position)
}
render()

onMounted(() => {
    // 性能监控end==================================>性能监控
    statsRef.value?.appendChild(stats.dom)
    // 性能监控end==================================>性能监控
    // 将渲染出来的容器放入到页面中（意思是将renderer.domElement元素渲染到页面中的containerRef元素中） 
    containerRef.value?.appendChild(renderer.domElement)


})

// 监听窗口变化
window.addEventListener('resize', () => {
    // 设置渲染器大小
    renderer.setSize(window.innerWidth, window.innerHeight)
    // // 设置相机宽高比
    camera.aspect = window.innerWidth / window.innerHeight
    // 相机属性变化需要执行updateProjectionMatrix方法
    camera.updateProjectionMatrix()
}, false)
onActivated(() => {

})


</script>

<style lang='less' scoped>
.container {
    height: 100%;
    width: 100%;
    margin: 0px;
    overflow: hidden;
}
</style>